﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.NetworkInformation;
using NetTraceLib;


namespace TestTraceLib
{
    /// <summary>
    /// QUICK and DIRTY test program to test route tracer. This should be discarded and replaced with proper unit tests.
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            new Program().PerformTrace();
        }

        /// <summary>
        /// The test program. Not build for efficiency... e.g. we can resolve names and cycle at once BUT this is to test the components individually.
        /// </summary>
        void PerformTrace()
        {
            string hostname;
            List<Task> tasks = new List<Task>();

            Console.Write("Enter hostname:");
            hostname = Console.ReadLine();

            Console.WriteLine("Discovering Route...");
            RouteTracer routeTracer = new RouteTracer(hostname, 32);
            routeTracer.NodeDiscoveryAttempted += NodeDiscoveryHandler;

            Task.WaitAll(routeTracer.DiscoverRoute());
            Console.WriteLine("Done with discovery.");

            Console.WriteLine("Resolving names...");

            foreach (RouteNode node in routeTracer.Nodes)
            {
                tasks.Add(node.UpdateHostInformation());
            }

            Task.WaitAll(tasks.ToArray());

            foreach (RouteNode node in routeTracer.Nodes)
            {
                Console.WriteLine("{0}:{1}", node.Distance, node.NodeName);
            }
            tasks.Clear();

            Console.WriteLine("Cycle Once.");

            foreach(RouteNode node in routeTracer.Nodes)
            {
                tasks.Add(node.UpdateCycle());
            }

            Task.WaitAll(tasks.ToArray());

            foreach(RouteNode node in routeTracer.Nodes)
            {
                Console.WriteLine("{0}:{1}:{2}:{3} ms", node.Distance, node.NodeName, node.Status.Status.ToString(), node.Status.ResponseTime);
            }
            tasks.Clear();


            Console.WriteLine("Done. Press <ENTER>.");
            Console.ReadLine();
        }


        void NodeDiscoveryHandler(object sender,TraceRouteDiscoveryEventArgs e)
        {
            string addressString ="";
            if(e.Reply.Address!=null)
            {
                addressString = e.Reply.Address.ToString();
            }
            Console.WriteLine("Hop {0}; Status {1}; Address {2}", e.Hop, e.Reply.Status.ToString(), addressString);            
        }

    }
}
